package com.kele.search.service;

import com.kele.common.model.response.PageResult;
import com.kele.model.goods.SearchGoods;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class Exam4SearchService {

    @Autowired
    RestHighLevelClient restHighLevelClient;

    /**
     * GET kele_goods/_search
     * {
     *   "query": {
     *     "bool": {
     *       "must": [
     *        {
     *          "match": {
     *            "title": "手机"
     *          }
     *        }],
     *        "filter": [
     *          {"range": {
     *            "price": {
     *              "gte": 1500,
     *              "lte": 2000
     *            }
     *          }}
     *        ]
     *     }
     *   },
     *   "from": 0,
     *   "size": 10,
     *   "sort": [
     *     {
     *       "price": {
     *         "order": "desc"
     *       }
     *     }
     *   ],
     *   "highlight": {
     *     "pre_tags": ["<strong style='color:red'>"],
     *     "post_tags": ["</strong>"],
     *     "fields": {
     *       "title": {}
     *     }
     *   }
     * }
     * @param pageNo
     * @param pageSize
     * @param searchMap
    {
        "title":"华为",
        "minPrice":1000,
        "maxPrice":2000,
        "sort":"desc"
    }
     * @return
     * @throws IOException
     * @throws ParseException
     */
    public PageResult<SearchGoods> search(Integer pageNo, Integer pageSize, Map searchMap)
            throws IOException, ParseException {

        //1 SearchRequset
        SearchRequest searchRequest = new SearchRequest("exam4");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        String title = (String)searchMap.get("title");
        if(!StringUtils.isEmpty(title)) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", title);
            searchSourceBuilder.query(matchQueryBuilder);
        }

        searchSourceBuilder.from((pageNo-1)*pageSize);//from
        searchSourceBuilder.size(pageSize);//size
        SortOrder sortOrder = SortOrder.ASC;
        String sort_order = (String)searchMap.get("sort");
        if(!StringUtils.isEmpty(sort_order)){
            if(sort_order.equals("desc")){
                sortOrder = SortOrder.DESC;
            }
        }
        searchSourceBuilder.sort("top",SortOrder.DESC);//sort
        searchSourceBuilder.sort("create_time",SortOrder.DESC);//sort

        HighlightBuilder highlightBuilder = new HighlightBuilder().field("title");
        highlightBuilder.preTags("<strong style='color:red'>");
        highlightBuilder.postTags("</strong>");
        searchSourceBuilder.highlighter(highlightBuilder);//hightlight

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchRes = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchRes.getHits();
        Long total = hits.getTotalHits().value;
        SearchHit[] hitsArray = hits.getHits();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<SearchGoods> records = new ArrayList<>();
        for (SearchHit documentFields : hitsArray) {
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
            SearchGoods searchGoods = new SearchGoods();
            searchGoods.setGoodsId((Long)sourceAsMap.get("goodsid"));
            searchGoods.setTitle((String)sourceAsMap.get("title"));
            searchGoods.setBrand((String)sourceAsMap.get("brand"));
            searchGoods.setPrice(new BigDecimal(sourceAsMap.get("price").toString()));
            searchGoods.setMainPic((String)sourceAsMap.get("main_pic"));
            if(!StringUtils.isEmpty((String)sourceAsMap.get("updatetime"))){
                searchGoods.setUpdateTime(simpleDateFormat.parse((String)sourceAsMap.get("updatetime")));
            }
            Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
            HighlightField highlightField = highlightFields.get("title");
            if(highlightField!=null){
                Text[] fragments = highlightField.getFragments();
                if(fragments!=null && fragments.length>0){
                    System.out.println(fragments[0]);
                    searchGoods.setTitle(fragments[0].string());
                }
            }
            records.add(searchGoods);
        }
        return new PageResult<>(total,records);
    }
}
